﻿Imports System.Text

' DEPENDENCIES:
'   Javascript
'   - jquery
'   - jquery.validate
'   - jquery.form
'   - bfmvc.app
'   - json2
'   - jsmin

'   CSS
'   - bfmvc.css
'   - jquery-ui-1.7.2
'   - style_ie6

Namespace AboutDNN.DNNMVC

#Region "JSHelper"
    Public Class JSHelper

        Public Enum DataTypeEnum
            html
            json
            xml
            script
            jsonp
            text
        End Enum

        Public Enum MethodEnum
            [get]
            [post]
        End Enum

        Private _data As New StringBuilder

        Public Shared Function Create() As JSHelper
            Return New JSHelper
        End Function

        Public Function Post(ByVal url As String, ByVal callback As JSHelper, ByVal type? As DataTypeEnum) As JSHelper
            Return Post(url, Nothing, callback, type)
        End Function

        Public Function Post(ByVal url As String, ByVal data As JSObject, ByVal callback As JSHelper, ByVal type? As DataTypeEnum) As JSHelper
            Return Ajax(MethodEnum.post, url, data, callback, type)
        End Function

        Public Function [Get](ByVal url As String, ByVal data As JSObject, ByVal callback As JSHelper, ByVal type? As DataTypeEnum) As JSHelper
            Return Ajax(MethodEnum.get, url, data, callback, type)
        End Function

        Public Function Ajax(ByVal method As MethodEnum, ByVal url As String, ByVal data As JSObject, ByVal callback As JSHelper, ByVal type As DataTypeEnum) As JSHelper
            Dim d As String = String.Empty
            If data IsNot Nothing AndAlso data.IsEmpty = False Then
                d = data.ToString
            End If
            Return Ajax(method, url, d, callback, type)
        End Function

        Public Function Ajax(ByVal method As MethodEnum, ByVal url As String, ByVal data As String, ByVal callback As JSHelper, ByVal type As DataTypeEnum) As JSHelper

            ' Post either provided values or the current form
            '   get request does not post the form
            Dim d = IIf(method = MethodEnum.get, "null", "bfmvc.getFormData()")
            If String.IsNullOrEmpty(data) = False Then
                d = data
            End If

            ' Specify the callback function
            Dim cb = "null"
            If callback IsNot Nothing AndAlso callback.IsEmpty = False Then
                cb = callback.ToString
            End If

            ' Wrap into a function call
            Return Wrap("{0} jQuery.{1}({2}, {3}, {4}, {5});", _
                        method.ToString, GetString(url), d, cb, GetString(type.ToString))

        End Function

        Public Function ShowMessage(ByVal msg As String) As JSHelper
            Return AddLine("bfmvc.showGlobalNotice({0})", GetString(msg))
        End Function

        Public Function Add(ByVal value As String) As JSHelper
            _data.Append(value)
            Return Me
        End Function

        Public Function Add(ByVal value As String, ByVal ParamArray params() As String) As JSHelper
            _data.AppendFormat(value, params)
            Return Me
        End Function

        Public Function AddLine(ByVal line As String) As JSHelper
            Return Add(" " & line).EndLine
        End Function

        Public Function AddLine(ByVal line As String, ByVal ParamArray params() As String) As JSHelper
            Return Add(" " & line, params).EndLine
        End Function

        Public Function EndLine() As JSHelper
            Return Add("; ")
        End Function

        Public Function SelectId(ByVal controlID As String, ByVal command As String) As JSHelper
            Return Add(JQHelper.Create.SelectID(controlID).AddCommand(command).ToString(True))
        End Function

        Public Function AddClass(ByVal elementID As String, ByVal className As String) As JSHelper
            Return SelectId(elementID, "addClass(" & className & ")").EndLine()
        End Function

        Public Function RemoveClass(ByVal elementId As String, ByVal classname As String) As JSHelper
            Return SelectId(elementId, "removeClass(" & classname & ")").EndLine()
        End Function


        Public Function IsEmpty() As Boolean
            Return _data.Length = 0
        End Function

        Public Function CancelEvent() As JSHelper
            Return AddLine("return false")
        End Function

        ' Wraps a validation check around the current script
        Public Function WrapValidation() As JSHelper
            Dim format = "if (jQuery('form').validate({{ onsubmit: false, debug: false }}).form()) {{ {0} }}"
            Return Wrap(format)
        End Function

        ' Wraps a validation check around the current script for the form specified
        Public Function WrapFormValidation(ByVal formName As String) As JSHelper
            Dim format = "if (jQuery('#" & formName & "').validate({{ onsubmit: false, debug: false }}).form()) {{ {0} }}"
            Return Wrap(format)
        End Function

        ' Wraps a validate check around the current script only for the input names specified
        Public Function WrapValidation(ByVal ParamArray inputNames() As String) As JSHelper
            'jQuery(formName).validate({{ onsubmit: false, debug: false }}).form();
            ' if (jQuery('#addnote_note').valid() && jQuery('#addtag_tagname').valid()) { statements; }
            If inputNames.Length > 0 Then
                Dim namesToValidate As String = String.Empty
                For Each name In inputNames
                    If namesToValidate <> String.Empty Then namesToValidate += " && "
                    namesToValidate += String.Format(" jQuery('#{0}').valid() ", name)
                Next

                Dim wrapFormat = " jQuery('form').validate({{ onsubmit: false, debug: false }}).form();  " & _
                                 " if (" & namesToValidate & ") {{ {0} }}"
                Wrap(wrapFormat)
            End If
            Return Me
        End Function

        ' Wraps a validation check around the current script for the group specified
        Public Function WrapGroupValidation(ByVal validationGroup As String) As JSHelper
            Dim format = "if (ValidateGroup_" & validationGroup & "()) {{ {0} }}"
            Return Wrap(format)
        End Function

        ' Wraps a confirmation check around the current script
        Public Function WrapConfirm(ByVal message As String) As JSHelper
            Dim format = "if (confirm({1})) {{ {0} }}"
            Return Wrap(format, JSHelper.GetString(message))
        End Function

        Public Function Wrap(ByVal format As String, ByVal ParamArray params() As String) As JSHelper
            ' Create the parameter object {0} is reserved for the current string
            Dim newparams = New List(Of String)
            newparams.Add(_data.ToString)
            If params.Length <> 0 Then
                newparams.AddRange(params)
            End If

            ' Format the value
            Dim newvalue = String.Format(format, newparams.ToArray)

            ' Replace existing value
            _data = New StringBuilder(newvalue)
            Return Me
        End Function

        Public Overrides Function ToString() As String
            Return _data.ToString
        End Function

        Public Function ToScript() As String
            Return ToString()
        End Function

        Public Function ToInline() As String
            Dim script = ToString.TrimEnd
            If script.EndsWith(";") = False Then
                script += "; "
            End If
            Return "javascript:" & script
        End Function

        Public Shared Function GetString(ByVal value As String) As String
            Return String.Format("'{0}'", CleanString(value))
        End Function

        Public Shared Function CleanString(ByVal value As String) As String
            If String.IsNullOrEmpty(value) Then
                Return value
            End If

            Dim sb As New StringBuilder
            For i As Integer = 0 To value.Length - 1
                Select Case value.Chars(i)
                    Case """"
                        sb.Append("\""")
                    Case "'"
                        sb.Append("\'")
                    Case "\"
                        sb.Append("\\")
                    Case ControlChars.Back
                        sb.Append("\b")
                    Case ControlChars.FormFeed
                        sb.Append("\f")
                    Case ControlChars.NewLine
                        sb.Append("\n")
                    Case ControlChars.Cr
                        sb.Append("\r")
                    Case ControlChars.Lf
                        If i > 0 AndAlso value.Chars(i - 1) <> ControlChars.Cr Then
                            sb.Append("\r")
                        End If
                    Case ControlChars.Tab
                        sb.Append("\t")
                    Case Else
                        sb.Append(value.Chars(i))
                End Select
            Next

            Return sb.ToString
        End Function

        Public Shared Function ShowElement(ByVal elementId As String) As JQHelper
            Return JQHelper.Create.SelectID(elementId).show
        End Function

        Public Shared Function ShowAndHideElement(ByVal showelement As String, ByVal hideelement As String) As JQHelper
            Return JQHelper.Create.SelectID(showelement).show.SelectID(hideelement).hide
        End Function

        Public Shared Function HideElement(ByVal elementId As String) As JQHelper
            Return JQHelper.Create.SelectID(elementId).hide
        End Function

        Public Shared Function ClearElement(ByVal elementId As String) As JQHelper
            Return JQHelper.Create.SelectID(elementId).clear
        End Function

        Public Shared Function ToggleElement(ByVal elementId As String) As JQHelper
            Return JQHelper.Create.SelectID(elementId).toggle
        End Function

        Public Shared Function Submit() As JSHelper
            Return JSHelper.Create.AddLine("jQuery(this).parents('form:eq(0)').trigger('submit')")
        End Function

        Public Shared Function Submit(ByVal formName As String) As JSHelper
            Dim js = New JSHelper
            js.AddLine("jQuery('#" & formName & "').trigger('submit')")
            Return js
        End Function

        Public Shared Function Submit(ByVal Validate As Boolean, ByVal ParamArray validateInputs() As String) As JSHelper
            Dim js = New JSHelper
            js.AddLine("jQuery('form').trigger('submit')")
            If Validate Then
                If validateInputs IsNot Nothing AndAlso validateInputs.Length > 0 Then
                    js.WrapValidation(validateInputs)
                Else
                    js.WrapValidation()
                End If
            End If
            Return js
        End Function

        Public Shared Function SubmitAjax(ByVal validate As Boolean, ByVal postUrl As String, ByVal updatePanel As String) As JSHelper
            Return SubmitAjax(validate, postUrl, updatePanel, Nothing)
        End Function

        Public Shared Function SubmitAjax(ByVal validate As Boolean, ByVal postUrl As String, ByVal updatePanel As String, ByVal ParamArray validateInputs() As String) As JSHelper
            'jQuery(formName).ajaxSubmit({target:'#addnote_container', url: '/thcrm/desktopmodules/thcrm/route.aspx?routec=notes&routea=add&entityid=260'});   
            Dim js = New JSHelper
            js.AddLine("jQuery('form').ajaxSubmit({ target: " & GetString("#" & updatePanel) & ", url: " & GetString(postUrl) & "})")
            If validate Then
                If validateInputs IsNot Nothing AndAlso validateInputs.Length > 0 Then
                    js.WrapValidation(validateInputs)
                Else
                    js.WrapValidation()
                End If
            End If
            Return js
        End Function

        Public Shared Function SetFocus(ByVal elementId As String) As String
            Return JQHelper.Create.SelectID(elementId).AddCommand("focus()").ToScriptBlock()
        End Function

        Private Shared Function jQuery_OnReady(ByVal statement As String) As String
            If statement.TrimEnd.EndsWith(";") = False Then statement += "; "

            Dim script As New StringBuilder
            script.Append("<script type='text/javascript'>")
            script.Append("jQuery(document).ready(function() { " & statement & "});")
            script.Append("</script>")

            Return script.ToString
        End Function

        Public Shared Function Load(ByVal url As String, ByVal elementid As String, ByVal toggle As Boolean) As JSHelper
            Dim js = New JSHelper
            If toggle Then
                js.Add("if(jQuery('#" & elementid & "').is(':visible')) { jQuery('#" & elementid & "').html('').hide(); } else { jQuery('#" & elementid & "').load('" & CleanString(url) & "').show(); }")
            Else
                js.Add("jQuery('#" & elementid & "').load('" & CleanString(url) & "').show();")
            End If
            Return js
        End Function

        Public Shared Function ValidateGroupScript(ByVal validationGroup As String) As String
            Dim functionName = "ValidateGroup_" & validationGroup
            Dim script = New StringBuilder
            script.AppendLine("<script type='text/javascript'>")
            script.AppendLine(" jQuery(document).ready(function() {")
            script.AppendLine("     jQuery('form').validate({onsubmit: false});")
            script.AppendLine("     jQuery('#" & validationGroup & " .causesValidation').click(" & functionName & ");")
            script.AppendLine("     jQuery('#" & validationGroup & " :text').keydown(function(evt) { if (evt.keyCode == 13) { " & functionName & "(evt); } });")
            script.AppendLine(" });")
            script.AppendLine(" function " & functionName & "(evt) {")
            script.AppendLine("     var isValid = true;")
            script.AppendLine("     jQuery('#" & validationGroup & "').find(':input').each(function(i, item) { if (!jQuery(item).valid()) isValid = false; });")
            script.AppendLine("     if (!isValid && evt) evt.preventDefault();")
            script.AppendLine("     return isValid;")
            script.AppendLine(" }")
            script.AppendLine("</script>")
            Return script.ToString
        End Function

    End Class
#End Region


#Region "AjaxRequest"
    Public Class AjaxRequest

        Public Shared Function Create(ByVal url As String) As AjaxRequest
            Return Create(url, Nothing)
        End Function

        Public Shared Function Create(ByVal url As String, ByVal ParamArray params() As String) As AjaxRequest
            Dim obj = New AjaxRequest
            If params IsNot Nothing Then
                obj._url = String.Format(url, params)
            Else
                obj._url = url
            End If
            Return obj
        End Function

        Private _url As String
        Private _updatepanel As String
        Private _removeElement As String
        Private _confirmMessage As String
        Private _successMessage As String
        Private _callback As String
        Private _validate As Boolean
        Private _postData As New JSObject
        Private _method As JSHelper.MethodEnum = JSHelper.MethodEnum.get
        Private _dataType As JSHelper.DataTypeEnum = JSHelper.DataTypeEnum.html
        Private _redirectToUrl As String
        Private _clearElement As String
        Private _clearInputs As String
        Private _loadUrl As String
        Private _loadElement As String
        Private _hideElement As String
        Private _showElement As String
        Private _removeClassElement As String
        Private _removeClassNames As String
        Private _focus As String
        Private _partialForm As String
        Private _clearForm As Boolean


        Public Function PartialForm(ByVal containerId As String) As AjaxRequest
            _partialForm = containerId
            Return Me
        End Function

        Public Function UpdatePanel(ByVal name As String) As AjaxRequest
            _updatepanel = name
            Return Me
        End Function

        Public Function UpdateRouteContent() As AjaxRequest
            _updatepanel = "RouteContentContainer"
            Return Me
        End Function
        Public Function RemoveElement(ByVal name As String) As AjaxRequest
            _removeElement = name
            Return Me
        End Function
        Public Function RedirectToUrl(ByVal url As String) As AjaxRequest
            _redirectToUrl = url
            Return Me
        End Function
        Public Function focus(ByVal elementId As String) As AjaxRequest
            _focus = elementId
            Return Me
        End Function
        Public Function ConfirmMessage(ByVal message As String) As AjaxRequest
            _confirmMessage = message
            Return Me
        End Function
        Public Function SuccessMessage(ByVal message As String) As AjaxRequest
            _successMessage = message
            Return Me
        End Function
        Public Function Callback(ByVal [function] As String) As AjaxRequest
            _callback = [function]
            Return Me
        End Function
        Public Function PostData(ByVal obj As JSObject) As AjaxRequest
            _postData.Merge(obj)
            Return Me
        End Function
        Public Function Validate() As AjaxRequest
            _validate = True
            Return Me
        End Function

        Public Function AddData(ByVal param As String, ByVal value As String) As AjaxRequest
            _postData.Add(param, value)
            Return Me
        End Function
        Public Function AddDataString(ByVal param As String, ByVal value As String) As AjaxRequest
            _postData.AddString(param, value)
            Return Me
        End Function
        Public Function Method(ByVal ajaxMethod As JSHelper.MethodEnum) As AjaxRequest
            _method = ajaxMethod
            Return Me
        End Function
        Public Function DataType(ByVal type As JSHelper.DataTypeEnum) As AjaxRequest
            _dataType = type
            Return Me
        End Function
        Public Function [Get]() As AjaxRequest
            Return Method(JSHelper.MethodEnum.get)
        End Function
        Public Function Post() As AjaxRequest
            Return Method(JSHelper.MethodEnum.post)
        End Function

        Public Function ClearElement(ByVal elementId As String) As AjaxRequest
            _clearElement = JQHelper.GetElementID(elementId)
            Return Me
        End Function
        Public Function ClearInput(ByVal inputIds As String) As AjaxRequest
            _clearInputs = inputIds
            Return Me
        End Function
        Public Function Load(ByVal url As String, ByVal elementid As String) As AjaxRequest
            _loadUrl = url
            _loadElement = JQHelper.GetElementID(elementid)
            Return Me
        End Function
        Public Function HideElement(ByVal ElementID As String) As AjaxRequest
            _hideElement = JQHelper.GetElementID(ElementID)
            Return Me
        End Function
        Public Function ShowElement(ByVal ElementID As String) As AjaxRequest
            _showElement = JQHelper.GetElementID(ElementID)
            Return Me
        End Function
        Public Function HideAndShowElement(ByVal HideElementID As String, ByVal ShowElementID As String) As AjaxRequest
            _hideElement = JQHelper.GetElementID(HideElementID)
            _showElement = JQHelper.GetElementID(ShowElementID)
            Return Me
        End Function


        Public Function RemoveClass(ByVal ElementID As String, ByVal ClassNames As String) As AjaxRequest
            _removeClassElement = JQHelper.GetElementID(ElementID)
            _removeClassNames = ClassNames
            Return Me
        End Function

        Public Function ClearForm() As AjaxRequest
            _clearForm = True
            Return Me
        End Function

        Private Function ToCallbackFunction() As JSHelper
            Dim callback = JSHelper.Create
            ' Update Panel
            If String.IsNullOrEmpty(_updatepanel) = False Then
                callback.SelectId(_updatepanel, "html(data)")
            End If
            ' Remove Element
            If String.IsNullOrEmpty(_removeElement) = False Then
                callback.SelectId(_removeElement, "remove()")
            End If
            ' Hide Element
            If String.IsNullOrEmpty(_hideElement) = False Then
                callback.SelectId(_hideElement, "hide()")
            End If
            ' Show Element
            If String.IsNullOrEmpty(_showElement) = False Then
                callback.SelectId(_showElement, "show()")
            End If
            ' Remove classes
            If String.IsNullOrEmpty(_removeClassElement) = False AndAlso String.IsNullOrEmpty(_removeClassNames) = False Then
                callback.SelectId(_removeClassElement, "removeClass(" & JSHelper.GetString(_removeClassNames) & ")")
            End If
            ' Callback function
            If String.IsNullOrEmpty(_callback) = False Then
                callback.AddLine(_callback)
            End If
            ' Show completed message
            If String.IsNullOrEmpty(_successMessage) = False Then
                callback.ShowMessage(_successMessage)
            End If
            ' Clear the form
            If _clearForm And String.IsNullOrEmpty(_partialForm) = False Then
                callback.AddLine(JQ.SelectFields(_partialForm).AddCommand("clearFields()").ToString)
                callback.AddLine(JQ.Select("form .error:not(label.error)").AddCommand("removeClass()").ToString)
                callback.AddLine(JQ.Select("label.error").AddCommand("remove()").ToString)
            ElseIf _validate Then
                callback.AddLine("jQuery('form .error').removeClass()")
                callback.AddLine("jQuery('label.error').remove()")
            End If
            ' Clear and hide an element
            If String.IsNullOrEmpty(_clearElement) = False Then
                callback.AddLine("jQuery('" & _clearElement & "').html('').hide()")
            End If
            ' Clear inputs
            If String.IsNullOrEmpty(_clearInputs) = False Then
                For Each i As String In _clearInputs.Split(",")
                    If i.Trim.Length = 0 Then Continue For
                    callback.AddLine("jQuery('#" & i.Trim & "').val('')")
                Next
            End If
            ' Set the focus
            If String.IsNullOrEmpty(_focus) = False Then
                callback.SelectId(_focus, "focus()")
            End If
            ' Redirect to url
            If String.IsNullOrEmpty(_redirectToUrl) = False Then
                callback.AddLine(" if (bfmvc.errorHappened == false) window.location = " & JSHelper.GetString(_redirectToUrl))
            End If
            ' Load data into element
            If String.IsNullOrEmpty(_loadUrl) = False AndAlso String.IsNullOrEmpty(_loadElement) = False Then
                callback.AddLine(" js.Add(""jQuery('" & _loadElement & "').load('" & JSHelper.CleanString(_loadUrl) & "').show()")
            End If

            Return callback.Wrap(" function(data) {{ {0} }} ")
        End Function

        Public Overrides Function ToString() As String
            Dim script = JSHelper.Create

            Dim data As String

            ' Get the data to post
            If _postData.IsEmpty And String.IsNullOrEmpty(_partialForm) Then
                _postData.AddString("emptyPost", "empty")
            End If

            ' Set the data to be posted to the JSON object
            data = _postData.ToString

            ' When posting a partial form then set the data to the serialized fields
            If String.IsNullOrEmpty(_partialForm) = False Then
                data = String.Format(JQ.SelectFields(_partialForm).AddCommand("fieldSerialize()").ToString)
            End If

            ' Crete the AJAX request
            script.Ajax(_method, _url, data, ToCallbackFunction, _dataType)

            ' Wrap the ajax call with confirm
            If String.IsNullOrEmpty(_confirmMessage) = False Then
                script.WrapConfirm(_confirmMessage)
            End If

            ' VALIDATION
            If _validate And String.IsNullOrEmpty(_partialForm) = False Then
                script.WrapGroupValidation(_partialForm)
            End If

            ' Return false
            script.Add("return false; ")

            ' Return the script
            Return script.ToString()
        End Function

        Public Shared Function JQ() As JQHelper
            Return JQHelper.Create
        End Function

    End Class
#End Region


#Region "AjaxForm"

    Public Class AjaxForm

        Private _formName As String = ""
        Private _url As String = ""
        Private _validate As Boolean = True
        Private _type As String = "POST"
        Private _dataType As String = "" ' xml || json || script || null (default)
        Private _target As String = "" ' element to be udpated
        Private _replaceTarget As Boolean = False ' Determine weather to replace the contents of the target or the whole target element
        Private _beforeSerialize As String = ""
        Private _beforeSubmit As String = ""
        Private _success As String = ""
        Private _resetForm As Boolean = False ' default = null
        Private _clearForm As Boolean = False ' default = null
        Private _wrapOnReady As Boolean = False
        Private _wrapScriptTag As Boolean = False

        Public Sub New()
        End Sub

        Public Shared Function Create(ByVal formName As String, ByVal url As String) As AjaxForm
            Return New AjaxForm With {._formName = formName, ._url = url}
        End Function

        Public Function DontValidate() As AjaxForm
            _validate = False
            Return Me
        End Function

        Public Function RequestType(ByVal value As String) As AjaxForm
            _type = value
            Return Me
        End Function

        Public Function DataType(ByVal value As String) As AjaxForm
            _dataType = value
            Return Me
        End Function

        Public Function json() As AjaxForm
            Return DataType("json")
        End Function

        Public Function Target(ByVal elementId As String) As AjaxForm
            _target = elementId
            Return Me
        End Function

        Public Function Target(ByVal elementId As String, ByVal replaceTarget As Boolean) As AjaxForm
            _target = elementId
            _replaceTarget = replaceTarget
            Return Me
        End Function

        Public Function BeforeSerialize(ByVal script As String) As AjaxForm
            _beforeSerialize = script
            Return Me
        End Function

        Public Function BeforeSubmit(ByVal functionName As String) As AjaxForm
            _beforeSubmit = functionName
            Return Me
        End Function

        Public Function Success(ByVal script As String) As AjaxForm
            _success = script
            Return Me
        End Function

        Public Function ClearForm() As AjaxForm
            _clearForm = True
            Return Me
        End Function

        Public Function ResetForm() As AjaxForm
            _resetForm = True
            Return Me
        End Function

        ' Wraps the code in a jQuery onready event
        Public Function OnReady() As AjaxForm
            Return OnReady(False)
        End Function

        ' Wraps the code in a jQuery onready event and adds a script tag if requested
        Public Function OnReady(ByVal addScriptTag As Boolean) As AjaxForm
            _wrapOnReady = True
            _wrapScriptTag = addScriptTag
            Return Me
        End Function

        Public Function AddScriptTag() As AjaxForm
            _wrapScriptTag = True
            Return Me
        End Function

        Public Overrides Function ToString() As String
            Dim options As New JSObject
            options.AddString("url", _url)
            options.AddString("type", _type)
            If _dataType <> "" Then
                options.AddString("dataType", _dataType)
            End If
            If _target <> "" Then
                options.AddString("target", _target)
                If _replaceTarget Then
                    options.Add("replaceTarget", "true")
                End If
            End If
            If _beforeSerialize <> "" And _validate = False Then
                options.Add("beforeSerialize", _beforeSerialize)
            ElseIf _beforeSerialize <> "" And _validate Then
                options.Add("beforeSerialize", "function(){ " & _beforeSerialize & "(); if (!jQuery('#" & _formName & "').validate().form()) return false; }")
            ElseIf _validate Then
                options.Add("beforeSerialize", "function() { if (!jQuery('#" & _formName & "').validate().form()) return false; }")
            End If
            If _beforeSubmit <> "" Then
                options.Add("beforeSubmit", _beforeSubmit)
            End If
            If _success <> "" Then
                options.Add("success", _success)
            End If
            If _resetForm Then
                options.Add("resetForm", "true")
            End If
            If _clearForm Then
                options.Add("clearForm", "true")
            End If

            Dim script As String = ""

            ' Add the script tag if requested
            If _wrapScriptTag Then script += "<script type='text/javascript'>"
            ' Add the jquery on ready tag
            If _wrapOnReady Then script += "jQuery(function(){"
            script += "jQuery('#" & _formName & "').ajaxForm(" + options.ToString + ");"
            ' Close the jquery on ready tag
            If _wrapOnReady Then script += "});"
            ' Close the script onready tag
            If _wrapScriptTag Then script += "</script>"

            Return script
        End Function

    End Class

#End Region


#Region "JSObject"
    Public Class JSObject

        Public Enum ValueTypeEnum
            [String]
            Other
        End Enum

        Public Shared Function Create() As JSObject
            Return New JSObject
        End Function

        Private _data As New Dictionary(Of String, String)

        Public Function Add(ByVal name As String, ByVal value As String) As JSObject
            If value = String.Empty Then
                value = "null"
            End If
            Return Add(name, value, ValueTypeEnum.Other)
        End Function

        Public Function AddString(ByVal name As String, ByVal value As String) As JSObject
            Return Add(name, value, ValueTypeEnum.String)
        End Function

        Public Function Add(ByVal name As String, ByVal value As String, ByVal ValueType As ValueTypeEnum) As JSObject
            Select Case ValueType
                Case ValueTypeEnum.String
                    _data.Add(name, JSHelper.GetString(value))
                Case ValueTypeEnum.Other
                    _data.Add(name, value)
            End Select
            Return Me
        End Function

        Public ReadOnly Property Data() As Dictionary(Of String, String)
            Get
                Return _data
            End Get
        End Property

        Public Function Merge(ByVal obj As JSObject) As JSObject
            For Each key As String In obj.Data.Keys
                _data.Add(key, obj.Data(key))
            Next
            Return Me
        End Function

        Public Function Count() As Integer
            Return _data.Count
        End Function

        Public Function IsEmpty() As Boolean
            Return Count() = 0
        End Function

        Public Overrides Function ToString() As String
            Dim sb = New StringBuilder
            sb.Append(" { ")
            Dim first As Boolean = True
            For Each key As String In _data.Keys
                If first = False Then
                    sb.Append(", ")
                End If
                first = False
                sb.AppendFormat("{0}: {1}", key, _data(key))
            Next
            sb.Append(" } ")
            Return sb.ToString
        End Function
    End Class
#End Region


#Region "JQHelper"
    Public Class JQHelper

        Private builder As New StringBuilder

        Public Function IsEmpty() As Boolean
            Return builder.ToString = String.Empty
        End Function

        Public Shared Function Create() As JQHelper
            Return New JQHelper
        End Function

        Public Function [Select](ByVal selector As String) As JQHelper
            If IsEmpty() = False AndAlso builder.ToString.TrimEnd.EndsWith(";") = False Then
                builder.Append(";")
            End If
            builder.AppendFormat("jQuery('{0}')", selector)
            Return Me
        End Function

        Public Function SelectID(ByVal selector As String) As JQHelper
            Return [Select](GetElementID(selector))
        End Function

        Public Function SelectFields(ByVal container As String) As JQHelper
            Return [Select](String.Format("#{0} :input, #{0} select, #{0} textarea", container))
        End Function

        Public Function addClass(ByVal className As String) As JQHelper
            Return AddCommand("addClass({0})", GetString(className))
        End Function

        Public Function removeClass(ByVal className As String) As JQHelper
            Return AddCommand("removeClass({0})", GetString(className))
        End Function

        Public Function show() As JQHelper
            Return AddCommand("show()")
        End Function

        Public Function hide() As JQHelper
            Return AddCommand("hide()")
        End Function

        Public Function toggle() As JQHelper
            Return AddCommand("toggle()")
        End Function

        Public Function toggleClass(ByVal className As String) As JQHelper
            Return AddCommand("toggleClass(" & JSHelper.GetString(className) & ")")
        End Function

        Public Function clear() As JQHelper
            AddCommand("html('')")
            AddCommand("hide()")
            Return Me
        End Function

        Public Function setfocus(ByVal elementid As String) As JQHelper
            Return SelectID(elementid).focus()
        End Function

        Public Function focus() As JQHelper
            Return AddCommand("focus()")
        End Function

        'Public Function onEnterTrigger(ByVal elementId As String, ByVal triggerElementId As String, ByVal eventName As String, ByVal cancelEvent As Boolean) As JQHelper
        '    SelectID(elementId)

        '    Dim cmd = New StringBuilder
        '    cmd.Append("keyup(function(event) { ")
        '    cmd.Append("    if (event.keyCode == 13) {")
        '    cmd.AppendFormat(" jQuery('{0}').trigger(jQuery.Event({1}));", GetElementID(triggerElementId), GetString(eventName))
        '    If cancelEvent Then
        '        cmd.Append("    return false; ")
        '    End If
        '    cmd.Append(" }})")

        '    Return AddCommand(cmd.ToString)
        'End Function

        Public Function AddCommand(ByVal statement As String, ByVal ParamArray params() As String) As JQHelper
            If builder.ToString.EndsWith(".") = False Then builder.Append(".")
            If params IsNot Nothing AndAlso params.Length > 0 Then
                builder.AppendFormat(statement, params)
            Else
                builder.Append(statement)
            End If
            Return Me
        End Function

        Private Function GetString(ByVal Data As String) As String
            Return JSHelper.GetString(Data)
        End Function

        Public Shared Function GetElementID(ByVal elementid As String) As String
            elementid = elementid.Trim
            If elementid.StartsWith("#") = False Then
                elementid = "#" & elementid
            End If
            Return elementid
        End Function

        Public Overrides Function ToString() As String
            Return ToString(False)
        End Function

        Public Overloads Function ToString(ByVal AddSemicolonAtTheEnd As Boolean) As String
            If AddSemicolonAtTheEnd AndAlso builder.ToString.Trim.EndsWith(";") = False Then
                builder.Append(";")
            End If
            Return builder.ToString
        End Function

        Public Function ToScriptBlock() As String
            Dim script = New StringBuilder
            script.Append(" <script type='text/javascript'> ")
            script.Append("jQuery(document).ready(function(){ ")
            script.Append("   " & ToString(True))
            script.Append(" }); ")
            script.Append(" </script>")
            Return script.ToString
        End Function

    End Class
#End Region

End Namespace
